import React, { useState, useEffect, useCallback } from 'react';
import styles from './ColorPicker.module.css';
import type { ColorPickerProps } from './type';

const ColorPicker: React.FC<ColorPickerProps> = ({
  value = '#ff0000',
  onChange,
  onCancel,
  onConfirm,
}) => {
  const [show, setShow] = useState(false);
  const [color, setColor] = useState(value);
  const [hue, setHue] = useState(0);
  const [input, setInput] = useState(value);
  const panelRef = React.useRef<HTMLDivElement>(null);

  // 生成色相条的渐变色
  const hueGradient =
    'linear-gradient(to bottom, #ff0000 0%, #ff00ff 17%, #0000ff 33%, #00ffff 50%, #00ff00 67%, #ffff00 83%, #ff0000 100%)';

  // 计算主色块的渐变背景
  const mainGradient = `linear-gradient(to right, #000, hsl(${hue}, 100%, 50%), #000)`;

  // 处理点击外部关闭面板
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (panelRef.current && !panelRef.current.contains(event.target as Node)) {
        setShow(false);
      }
    };

    if (show) {
      document.addEventListener('mousedown', handleClickOutside);
    }
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [show]);

  // 选择色相
  const handleHueChange = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const y = e.clientY - rect.top;
    const percent = Math.max(0, Math.min(1, y / rect.height));
    const newHue = Math.round(percent * 360);
    setHue(newHue);
    const newColor = `hsl(${newHue}, 100%, 50%)`;
    setColor(newColor);
    setInput(rgbToHex(newColor));
    onChange?.(rgbToHex(newColor));
  }, [onChange]);

  // 主色块取色
  const handleMainClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const percent = Math.max(0, Math.min(1, x / rect.width));
    const newColor = `hsl(${hue}, 100%, ${Math.round(percent * 100)}%)`;
    setColor(newColor);
    setInput(rgbToHex(newColor));
    onChange?.(rgbToHex(newColor));
  }, [hue, onChange]);

  // 输入框变更
  const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setInput(newValue);
    if (/^#[0-9A-Fa-f]{6}$/.test(newValue)) {
      setColor(newValue);
      onChange?.(newValue);
    }
  }, [onChange]);

  // 颜色格式转换
  const rgbToHex = (hsl: string): string => {
    const match = hsl.match(/hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)/);
    if (!match) return hsl;

    const h = parseInt(match[1]) / 360;
    const s = parseInt(match[2]) / 100;
    const l = parseInt(match[3]) / 100;

    let r, g, b;

    if (s === 0) {
      r = g = b = l;
    }
    else {
      const hue2rgb = (p: number, q: number, t: number) => {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1 / 6) return p + (q - p) * 6 * t;
        if (t < 1 / 2) return q;
        if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
        return p;
      };

      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      r = hue2rgb(p, q, h + 1 / 3);
      g = hue2rgb(p, q, h);
      b = hue2rgb(p, q, h - 1 / 3);
    }
    const toHex = (x: number) => {
      const hex = Math.round(x * 255).toString(16);
      return hex.length === 1 ? '0' + hex : hex;
    };
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
  };

  return (
    <div className={styles.colorPicker}>
      <div
        className={styles.icon}
        onClick={() => setShow(!show)}
        style={{ backgroundColor: color }}
      />
  {show && (
        <div className={styles.panel} ref={panelRef}>
          <div className={styles.changColor}>
          <div
            className={styles.main}
            style={{ background: mainGradient }}
            onClick={handleMainClick}
          />
          <div
            className={styles.hueBar}
            style={{ background: hueGradient }}
            onClick={handleHueChange}
          />
          </div>
          <div className={styles.select}>
          <input
            className={styles.input}
            value={input}
            onChange={handleInputChange}
            maxLength={7}
          />
          <div
            className={styles.preview}
            style={{ background: color }}
          />
          </div>
          <div className={styles.actions}>
            <button onClick={onCancel}>取消</button>
            <button onClick={() => onConfirm?.(color)}>确定</button>
          </div>
        </div>
      )}
    </div>
  );
};

export default ColorPicker; 